// cf-617e
// 题意：给定n(<=100000)个数，现在有m(<=100000)个询问，每个询问是一个区间
//       [l, r]，要求这个区间内有多少(i, j)对使得a[i]^a[i+1]^...^a[j]=k
//       （l<=i<=j<=r），k是给定的。
//
// 题解：没修改离线区间询问，这题可以用莫队算法。
//       先维护出前缀异或和，然后对于每个位置的前缀疑惑和a，add就是
//       答案就加上当前区间维护有的count[a^k]，然后count[a]++，
//       remove也是类似只是顺序反过来。这样就可以套用经典的莫队了。
//
// run: $exec < input
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>

int const maxn = 100007;
int const size = std::sqrt(maxn);
int prefix[maxn];
int count[1 << 20] = {1};
long long ans[maxn];
int n, m, k;
long long cur_ans;

struct query { int l, r, id; };
std::vector<query> q;

bool mo_cmp(query const & a, query const & b)
{
	if (a.l / size != b.l / size) return a.l / size < b.l / size;
	else return (a.r < b.r) ^ ((a.l / size) & 1); // faster
//	else return a.r < b.r;
}

void mo_add(int x)
{
	cur_ans += count[k ^ x];
	count[x]++;
}

void mo_remove(int x)
{
	count[x]--;
	cur_ans -= count[k ^ x];
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> m >> k;
	for (int i = 1; i <= n; i++) {
		std::cin >> prefix[i];
		prefix[i] ^= prefix[i - 1];
	}

	q.resize(m);
	for (int i = 0; i < m; i++) {
		std::cin >> q[i].l >> q[i].r;
		q[i].l--;
		q[i].id = i;
	}
	std::sort(q.begin(), q.end(), mo_cmp);
	// mo's algorithm main part
	int l = 0, r = 0;
	for (auto i : q) {
		while (l < i.l) mo_remove(prefix[l++]);
		while (l > i.l) mo_add(prefix[--l]);
		while (r > i.r) mo_remove(prefix[r--]);
		while (r < i.r) mo_add(prefix[++r]);
		ans[i.id] = cur_ans;
	}
	for (int i = 0; i < m; i++)
		std::cout << ans[i] << '\n';
}

